package com.gdut.huayan.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.gdut.huayan.constant.SecurityConstant;
import com.gdut.huayan.dao.FilePathMapper;
import com.gdut.huayan.dao.FileSystemMapper;
import com.gdut.huayan.entity.dto.PageQuery;
import com.gdut.huayan.entity.po.FilePath;
import com.gdut.huayan.entity.po.FileSystem;
import com.gdut.huayan.entity.vo.FileUpload;
import com.gdut.huayan.service.FileService;
import com.gdut.huayan.service.exception.BaseException;
import com.gdut.huayan.utils.AliyunUtils;
import com.gdut.huayan.utils.RedisUtils;
import com.gdut.huayan.utils.SecurityUtils;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.tomcat.util.security.ConcurrentMessageDigest;
import org.apache.tomcat.util.security.MD5Encoder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.Date;
import java.util.Map;
import java.util.Objects;
import java.util.UUID;

@Service
public class FileServiceImpl implements FileService {

    private final String REDIS_PREFIX = "FILE-TEMP-";

    @Autowired
    private FilePathMapper filePathMapper;

//    @Autowired
//    private FileSystemMapper fileSystemMapper;

    @Autowired
    private RedisUtils redisUtils;

    private String getMD5(String s) {
        return MD5Encoder.encode(ConcurrentMessageDigest.digestMD5(s.getBytes()));
    }


    public void authCheck(Long userId, Boolean authFlag) {
        if (authFlag) {
            return;
        }
        if (!Objects.equals(userId, SecurityUtils.getUserIdNumber())) {
            throw new BaseException(403, "file:文件权限不足！");
        }
    }


    @Override
    @Transactional
    public Map<String, Object> requestUpload(FileUpload fileUpload) {
        System.out.println("我要去要个上传连接");
        String requestId = UUID.randomUUID().toString();
        //TODO 判断空指针
        String fileName =
                UUID.randomUUID() + "." + fileUpload.getFileName();

        FilePath filePath = new FilePath();
        filePath.setFileName(fileName);
        filePath.setStatus(2);
        filePath.setCreateTime(LocalDateTime.now());
        filePath.setCreateUserId(SecurityUtils.getUserIdNumber());
        filePath.setContentType(fileUpload.getContentType());
        String urlPath = fileUpload.getUrlPath();
        urlPath = urlPath.substring(1);
        filePath.setFileFullPath(urlPath + fileUpload.getFileName());//路径名称
        long expire = new Date().getTime() + 1000 * fileUpload.getExpireTime();

        String uploadLink = AliyunUtils.getUploadLink(filePath.getFileFullPath(), filePath.getContentType(), expire);
        redisUtils.put(REDIS_PREFIX + requestId, JSONObject.toJSONString(filePath), SecurityConstant.TIME_TWENTY_MINUTES);

        String signature = getMD5(uploadLink + requestId);

        assert uploadLink != null;
        return Map.of("requestId", requestId,
                "uploadLink", uploadLink,
                "signature", signature,
                "expire", expire);
    }

    /**
     * 通过requestId去redis里拿filepath
     *
     * @param requestId 请求上传requestUpload的返回结果
     * @param type
     * @return
     */
    @Override
    @Transactional
    public Long getFileStatus(String requestId, boolean type) {
        if (requestId == null) {
            return null;
        }
        FilePath filePath = JSONObject.parseObject(redisUtils.get(REDIS_PREFIX + requestId), FilePath.class);
        if (filePath == null) {
            throw new BaseException(4000, "图片上传失败请重新申请上传");
        }
        if (AliyunUtils.fileIsExist(filePath.getFileFullPath())) {
            filePathMapper.insert(filePath);
            redisUtils.remove(REDIS_PREFIX + requestId);
            System.out.println(filePath.getId());
            return filePath.getId();
        } else {
            if (type) {
                throw new BaseException(404, "file:文件不存在，上传失败");
            }
            return null;
        }
    }


    @Override
    @Transactional
    public Map<String, Object> requestUpdate(FileUpload fileUpload, Boolean authFlag) {
        String requestId = UUID.randomUUID().toString();
        FilePath filePath = filePathMapper.selectById(fileUpload.getFileId());
//        FileSystem fileSystem = fileSystemMapper.selectById(filePath.getFileSystemId());
        authCheck(filePath.getCreateUserId(), authFlag);
//        if (fileSystem.getIsUpdated()) {
        filePath.setFileName(UUID.randomUUID() + "." + fileUpload.getFileName());
        filePath.setContentType(fileUpload.getContentType());
        filePath.setFileFullPath(fileUpload.getUrlPath() + "/" + filePath.getFileName());
        redisUtils.put(REDIS_PREFIX + requestId, JSONObject.toJSONString(filePath), SecurityConstant.TIME_TWENTY_MINUTES);
        long expire = new Date().getTime() + 1000 * fileUpload.getExpireTime();
        String uploadLink = AliyunUtils.getUploadLink(filePath.getFileFullPath(), filePath.getContentType(), expire);
        String signature = getMD5(uploadLink + requestId);
        assert uploadLink != null;
        return Map.of("requestId", requestId,
                "uploadLink", uploadLink,
                "signature", signature,
                "expire", expire);
//        } else {
//            throw new BaseException(403, "file:文件不允许更改");
//        }
    }

    @Override
    @Transactional
    public void requestUpdateConfirm(String requestId) {
        FilePath filePath = JSONObject.parseObject(redisUtils.get(REDIS_PREFIX + requestId), FilePath.class);
        if (filePath == null) {
            throw new BaseException(4000, "图片上传失败请重新申请上传");
        }
        boolean isExist = AliyunUtils.fileIsExist(filePath.getFileFullPath());
        if (isExist) {
            FilePath old = filePathMapper.selectById(filePath.getId());
            AliyunUtils.deleteFile(old.getFileFullPath());
            filePathMapper.updateById(filePath);
            redisUtils.remove(REDIS_PREFIX + requestId);
        } else {
            throw new BaseException(404, "file:新文件未找到");
        }
    }

    @Override
    public Map<String, Object> requestFile(Long fileId, Long expireTime, Boolean authFlag) {
        FilePath filePath = filePathMapper.selectById(fileId);
//        FileSystem fileSystem  = fileSystemMapper.selectById(filePath.getFileSystemId());
//        if (fileSystem.getIsPrivate()) {
//            authCheck(filePath.getCreateUserId(),authFlag);
//        }

        long expire = new Date().getTime() + 1000 * expireTime;

        return Map.of("rawData", filePath,
                "downloadLink", Objects.requireNonNull(AliyunUtils.getDownloadLink(filePath.getFileFullPath(), expire)),
                "expireTime", expire);
    }

    @Override
    @Transactional
    public void requestDelete(Long fileId, Boolean authFlag) {
        FilePath filePath = filePathMapper.selectById(fileId);
        authCheck(filePath.getCreateUserId(), authFlag);
        filePathMapper.deleteById(fileId);
        AliyunUtils.deleteFile(filePath.getFileFullPath());
//        FileSystem fileSystem  = fileSystemMapper.selectById(filePath.getFileSystemId());
//        if(fileSystem.getIsConnected()){
//            filePath.setStatus(3);
//            filePathMapper.updateById(filePath);
//        }else{
//            filePathMapper.deleteById(fileId);
//            AliyunUtils.deleteFile(filePath.getFileFullPath());
//        }
    }

}
